package com.example.waimai.serviceImp;

import com.example.waimai.mapper.OrdersMapper;
import com.example.waimai.mapper.UserAddressMapper;
import com.example.waimai.pojo.*;
import com.example.waimai.service.OrdersService;
import com.example.waimai.util.RedisLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.data.geo.*;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.ArrayList;
import java.util.List;


@Service
public class OrdersServiceImp implements OrdersService {

    @Autowired
    private OrdersMapper ordersMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserAddressServiceImp userAddressServiceImp;
    @Autowired
    private StoreAddressServiceImp storeAddressServiceImp;

    @Autowired
    private StoreServiceImp storeServiceImp;

    @Autowired
    private RedisLock redisLock;

    // 带有地址信息的订单
    String key = "missedOrder";

    @Autowired
    private MyRabbitService myRabbitService;


    @Override
    public Orders insertNewOrder(Orders order) {
        int result = ordersMapper.insertNewOrder(order);

        // 这个操作应该延后
        // 将生成的订单 放到 Redis的 GeoHash中 用于接下来的附近的查找
        // 以订单为单位
        // 操作指令 geoadd key 坐标 坐标 名称
        // key missedOrder  xx xx  order:orderId
        String name = "orders:"+order.getId();

        // 发送 消息 到消息队列中，由 Boss客户端进行处理
        String exchange = "Bossorders";
        String routekey = "store:"+order.getStoreId();
        System.out.println("routeKey:"+routekey);
        myRabbitService.sendOrderToBoss(exchange,routekey,order);

        // 存储订单对应的用户地址信息
        UserAddress address = userAddressServiceImp.getAddressByUserAddressId(order.getUserAddressId());
        // 存储对应的信息 在 redis key: userAddr:order:订单Id   value:用户地址
        String addrKey =  "userAddr:order:"+order.getId();
        redisTemplate.opsForValue().set(addrKey,address);

        // 存储地址信息
       /* Point point = new Point(Double.parseDouble(address.getLongitude()),Double.parseDouble(address.getLatitude())) ; // 获取用户地址的经纬度
        RedisGeoCommands.GeoLocation<String> geoLocation = new RedisGeoCommands.GeoLocation<>(name,point);
        redisTemplate.opsForGeo().add(key,geoLocation);*/
        return order;
    }

    // 骑手查询附近的订单
    @Override
    public List<RiderOrder> getOrdersByRider(Point point,Integer riderId) {
        //RedisGeoCommands.GeoLocation<String> location = new RedisGeoCommands.GeoLocation<>(name,point);
        //redisTemplate.opsForGeo().add(key,location);
        // 寻找
        Distance distance = new Distance(5,Metrics.KILOMETERS);
        Circle circle = new Circle(point,distance);
        GeoResults radius = redisTemplate.opsForGeo().radius(key,circle);
        List<GeoResult> content = radius.getContent();
        List<RiderOrder> result = new ArrayList<>();
        for(GeoResult c : content){
            RiderOrder riderOrder = new RiderOrder();
            RedisGeoCommands.GeoLocation<String> s = (RedisGeoCommands.GeoLocation) c.getContent();
            String member = s.getName();
            member = member.split(":")[1];
            String key = "userAddr:order:"+member;  // 订单 ： 用户地址信息

            // 订单信息
            Orders order = ordersMapper.getOrderById(Integer.parseInt(member));
            riderOrder.setOrder(order);

            // 获取到 UserAddress信息
            UserAddress userAddress = (UserAddress) redisTemplate.opsForValue().get(key);
            if(userAddress == null){
                // 使用数据库查询  根据订单上的USeAddresID 来查询
                userAddress = userAddressServiceImp.getAddressByUserAddressId(order.getUserAddressId());
                redisTemplate.opsForValue().set(key,userAddress);
            }
            riderOrder.setUserAddress(userAddress);

            // 可以将 storeAddress 放到 Redis中
            StoreAddress storeAddress = (StoreAddress) redisTemplate.opsForValue().get("StoreAddr:"+order.getStoreId());
            if(storeAddress == null){
                storeAddress =  storeAddressServiceImp.getStoreAddressById(order.getStoreId());
            }
            // 店铺地址信息
            riderOrder.setStoreAddress(storeAddress);

            // 获取一下店铺的名称
            Store store = (Store) redisTemplate.opsForValue().get("Store:"+order.getStoreId());
            riderOrder.setStoreName(store.getStoreName());
            result.add(riderOrder);
        }
        System.out.println("xxxxx");
        return result;
    }



    /*
    * 抢单成功，订单状态进行改变。 同时将订单的信息从 redis中删除  zzset 删除
    * 返回 抢单成功或者失败的信息
    * */
    public Boolean riderRobOrder(Integer riderId,Integer orderId){
        // RiderId 用于改变订单的信息
        // orderId  则是对应 reids中的分布式锁
        // 尝试获取分布式锁
        String lockKey = "orderLock:"+orderId;
        boolean getlock = redisLock.lock(lockKey,5);
        if(getlock){
            // 获取到锁  抢单成功
            String kk = "order:"+orderId;
            // 将订单的地址信息从 GeoHash中移除
            redisTemplate.opsForZSet().remove(key,kk);
            // 修改订单状态
            Orders orders = new Orders();
            orders.setRiderId(riderId);
            orders.setId(orderId);
            orders.setRiderStatus(1); // 状态 由骑手未接单转换为 未取货
            ordersMapper.updateOrder(orders);
            // 订单修改完毕后返回结果
            redisLock.unlock(lockKey);
        }else{
            // 抢单失败
            return false;
        }

        return true;

    }

    /*
    * 获取到 骑手 已经接到的 订单信息 （还未取到货）
    * */
    @Override
    public List<RiderOrder> getOrdersByStatus(Integer riderId, Integer riderStatus) {
        // 首先获取到所有的Order
        List<Orders> orders = ordersMapper.getOrdersByIdAndStatus(riderId, riderStatus);
        List<RiderOrder> result = new ArrayList<>();
        for(Orders order : orders){
            RiderOrder riderOrder = new RiderOrder();
            // 获取店铺信息
            String storeName = ( (Store) redisTemplate.opsForValue().get("Store:"+order.getStoreId()) ).getStoreName();
            if(storeName == null){

            }
            // 获取店铺的地址信息
            StoreAddress storeAddress = (StoreAddress) redisTemplate.opsForValue().get("StoreAddr:"+order.getStoreId());
            if(storeAddress == null){
                storeAddress = storeAddressServiceImp.getStoreAddressById(order.getStoreId());
            }
            // 获取用户的地址信息
            UserAddress userAddress = (UserAddress) redisTemplate.opsForValue().get(" userAddr:order:"+order.getStoreId());
            if(userAddress == null){
                userAddress = userAddressServiceImp.getAddressByUserAddressId(order.getUserAddressId());
            }
            riderOrder.setStoreAddress(storeAddress);
            riderOrder.setUserAddress(userAddress);
            riderOrder.setOrder(order);
            riderOrder.setStoreName(storeName);
            result.add(riderOrder);
        }
        return result;
    }

    @Override
    public Integer updateOrderByRider(Orders order) {
        int i = ordersMapper.updateOrder(order);
        return i;
    }

    @Override
    public List<RiderOrder> getRiderAllOrder(Integer riderId) {
        // 先获取到订单，再将订单需要的 UserAddress 和 StoreAddress填入
        List<RiderOrder> result = new ArrayList<>();
        List<Orders> orders = ordersMapper.getOrdersByRiderId(riderId);
        for(Orders order : orders){
            RiderOrder riderOrder = new RiderOrder();
            riderOrder.setOrder(order);
            UserAddress userAddress  = (UserAddress) redisTemplate.opsForValue().get("userAddr:order:"+order.getId());
            if(userAddress == null){
                userAddress = userAddressServiceImp.getAddressByUserAddressId(order.getUserAddressId());
                redisTemplate.opsForValue().set("userAddr:order:"+order.getId(),userAddress);
            }
            riderOrder.setUserAddress(userAddress);
            StoreAddress storeAddress = (StoreAddress) redisTemplate.opsForValue().get("StoreAddr:"+order.getStoreId());
            if(storeAddress == null){
                storeAddress = storeAddressServiceImp.getStoreAddressById(order.getStoreId());
                redisTemplate.opsForValue().set("StoreAddr:"+order.getStoreId(),storeAddress);
            }
            riderOrder.setStoreAddress(storeAddress);
            String storeName = ( (Store) redisTemplate.opsForValue().get("Store:"+order.getStoreId()) ).getStoreName();
            if(storeName == null){

            }
            riderOrder.setStoreName(storeName);
            result.add(riderOrder);
        }
        return result;
    }


    public List<Orders> getOrderByRiderIdAndUserStatus(Integer RiderId){
        return ordersMapper.getOrdersByRiderIdAndUserStauts(RiderId,2);
    }

    @Override
    public List<Orders> getOrdersByBoosIdAndUserStatus(Integer bossId) {
        return ordersMapper.getOrdersByBossIdAndUserStatus(bossId,2);
    }

    @Override
    public Boolean cancleOrder(Orders order) {
        int result = ordersMapper.updateOrder(order);
        if(result == 1){
            // 取消成功，通知用户
            String exchange = "UserOrders";
            String routeKey = "user:"+order.getUserId();
            myRabbitService.sendOrder(exchange,routeKey,order);
        }
        return result == 1;
    }
}
